package services

import (
	"errors"
	"simple-crm/config"
	"simple-crm/models"
	"simple-crm/utils"
	"time"

	"gorm.io/gorm"
)

type UserService struct {
	db  *gorm.DB
	cfg *config.Config
}

func NewUserService(db *gorm.DB, cfg *config.Config) *UserService {
	return &UserService{db: db, cfg: cfg}
}

// 用户登录
func (s *UserService) Login(username, password string) (*models.User, string, error) {
	var user models.User
	if err := s.db.Preload("Roles").Where("username = ? AND status = 'active'", username).First(&user).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, "", errors.New("用户名或密码错误")
		}
		return nil, "", err
	}
	
	// 验证密码
	if !utils.CheckPassword(password, user.Password) {
		return nil, "", errors.New("用户名或密码错误")
	}
	
	// 生成JWT令牌
	token, err := utils.GenerateJWT(user.ID, user.Username, s.cfg.JWT.Secret, s.cfg.JWT.ExpireTime)
	if err != nil {
		return nil, "", errors.New("生成令牌失败")
	}
	
	// 更新登录信息
	now := time.Now()
	s.db.Model(&user).Updates(map[string]interface{}{
		"last_login_at": &now,
		"login_count":   gorm.Expr("login_count + 1"),
	})
	
	return &user, token, nil
}

// 根据ID获取用户
func (s *UserService) GetUserByID(id uint) (*models.User, error) {
	var user models.User
	if err := s.db.Preload("Roles").First(&user, id).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

// 创建用户
func (s *UserService) CreateUser(user *models.User) error {
	// 检查用户名是否已存在
	var count int64
	s.db.Model(&models.User{}).Where("username = ?", user.Username).Count(&count)
	if count > 0 {
		return errors.New("用户名已存在")
	}
	
	// 加密密码
	hashedPassword, err := utils.HashPassword(user.Password)
	if err != nil {
		return err
	}
	user.Password = hashedPassword
	
	return s.db.Create(user).Error
}

// UpdateUser 更新用户（支持结构体参数）
func (s *UserService) UpdateUser(user *models.User) error {
	// 如果密码不为空，需要加密
	if user.Password != "" {
		hashedPassword, err := utils.HashPassword(user.Password)
		if err != nil {
			return err
		}
		user.Password = hashedPassword
	}
	
	return s.db.Model(user).Where("id = ?", user.ID).Updates(user).Error
}

// UpdateUserByMap 更新用户（支持map参数）
func (s *UserService) UpdateUserByMap(id uint, updates map[string]interface{}) error {
	// 如果更新密码，需要加密
	if password, ok := updates["password"]; ok {
		if passwordStr, ok := password.(string); ok && passwordStr != "" {
			hashedPassword, err := utils.HashPassword(passwordStr)
			if err != nil {
				return err
			}
			updates["password"] = hashedPassword
		}
	}
	
	return s.db.Model(&models.User{}).Where("id = ?", id).Updates(updates).Error
}

// 删除用户
func (s *UserService) DeleteUser(id uint) error {
	return s.db.Delete(&models.User{}, id).Error
}

// GetUsers 获取用户列表
func (s *UserService) GetUsers(page, limit int, search, status, roleID string) ([]models.User, int64, error) {
	offset := (page - 1) * limit
	
	query := s.db.Model(&models.User{}).Preload("Roles")
	
	if search != "" {
		query = query.Where("username LIKE ? OR real_name LIKE ? OR phone LIKE ?", 
			"%"+search+"%", "%"+search+"%", "%"+search+"%")
	}
	
	if status != "" {
		query = query.Where("status = ?", status)
	}
	
	if roleID != "" {
		query = query.Joins("JOIN user_roles ON users.id = user_roles.user_id").Where("user_roles.role_id = ?", roleID)
	}
	
	var total int64
	query.Count(&total)
	
	var users []models.User
	err := query.Offset(offset).Limit(limit).Find(&users).Error
	
	return users, total, err
}

// GetUsersCompat 获取用户列表（兼容旧接口）
func (s *UserService) GetUsersCompat(page, limit int, search, status string) ([]models.User, int64, error) {
	return s.GetUsers(page, limit, search, status, "")
}

// UpdatePassword 更新密码
func (s *UserService) UpdatePassword(userID uint, oldPassword, newPassword string) error {
	// 获取用户
	var user models.User
	if err := s.db.First(&user, userID).Error; err != nil {
		return err
	}

	// 验证旧密码
	if !utils.CheckPassword(oldPassword, user.Password) {
		return errors.New("旧密码错误")
	}

	// 加密新密码
	hashedPassword, err := utils.HashPassword(newPassword)
	if err != nil {
		return err
	}

	// 更新密码
	return s.db.Model(&user).Update("password", hashedPassword).Error
}

// GetUserStats 获取用户统计信息
func (s *UserService) GetUserStats() (map[string]interface{}, error) {
	stats := make(map[string]interface{})

	// 总用户数
	var totalUsers int64
	if err := s.db.Model(&models.User{}).Count(&totalUsers).Error; err != nil {
		return nil, err
	}
	stats["total_users"] = totalUsers

	// 活跃用户数
	var activeUsers int64
	if err := s.db.Model(&models.User{}).Where("status = ?", "active").Count(&activeUsers).Error; err != nil {
		return nil, err
	}
	stats["active_users"] = activeUsers

	// 非活跃用户数
	var inactiveUsers int64
	if err := s.db.Model(&models.User{}).Where("status != ?", "active").Count(&inactiveUsers).Error; err != nil {
		return nil, err
	}
	stats["inactive_users"] = inactiveUsers

	// 今日新增用户数
	today := time.Now().Format("2006-01-02")
	var todayUsers int64
	if err := s.db.Model(&models.User{}).Where("DATE(created_at) = ?", today).Count(&todayUsers).Error; err != nil {
		return nil, err
	}
	stats["today_users"] = todayUsers

	// 本月新增用户数
	thisMonth := time.Now().Format("2006-01")
	var monthUsers int64
	if err := s.db.Model(&models.User{}).Where("DATE_FORMAT(created_at, '%Y-%m') = ?", thisMonth).Count(&monthUsers).Error; err != nil {
		return nil, err
	}
	stats["month_users"] = monthUsers

	return stats, nil
}

// BatchDeleteUsers 批量删除用户
func (s *UserService) BatchDeleteUsers(userIDs []uint) error {
	// 检查是否包含管理员用户
	var adminCount int64
	if err := s.db.Model(&models.User{}).Where("id IN ? AND username = 'admin'", userIDs).Count(&adminCount).Error; err != nil {
		return err
	}
	if adminCount > 0 {
		return errors.New("不能删除管理员用户")
	}

	// 批量删除
	return s.db.Where("id IN ?", userIDs).Delete(&models.User{}).Error
}

// ResetPassword 重置用户密码
func (s *UserService) ResetPassword(userID uint, newPassword string) error {
	// 加密新密码
	hashedPassword, err := utils.HashPassword(newPassword)
	if err != nil {
		return err
	}

	// 更新密码
	return s.db.Model(&models.User{}).Where("id = ?", userID).Update("password", hashedPassword).Error
}

// ToggleUserStatus 切换用户状态
func (s *UserService) ToggleUserStatus(userID uint) error {
	// 获取当前用户
	var user models.User
	if err := s.db.First(&user, userID).Error; err != nil {
		return err
	}

	// 检查是否为管理员
	if user.Username == "admin" {
		return errors.New("不能修改管理员状态")
	}

	// 切换状态
	newStatus := "active"
	if user.Status == "active" {
		newStatus = "inactive"
	}

	return s.db.Model(&user).Update("status", newStatus).Error
}

// GetUsersByRole 根据角色获取用户列表
func (s *UserService) GetUsersByRole(roleID uint) ([]models.User, error) {
	var users []models.User
	err := s.db.Joins("JOIN user_roles ON users.id = user_roles.user_id").
		Where("user_roles.role_id = ?", roleID).
		Find(&users).Error
	return users, err
}

// GetUserRoles 获取用户的所有角色
func (s *UserService) GetUserRoles(userID uint) ([]models.Role, error) {
	var roles []models.Role
	err := s.db.Joins("JOIN user_roles ON roles.id = user_roles.role_id").
		Where("user_roles.user_id = ?", userID).
		Find(&roles).Error
	return roles, err
}

// CheckUserExists 检查用户是否存在
func (s *UserService) CheckUserExists(username string) (bool, error) {
	var count int64
	err := s.db.Model(&models.User{}).Where("username = ?", username).Count(&count).Error
	return count > 0, err
}

// CheckEmailExists 检查邮箱是否存在
func (s *UserService) CheckEmailExists(email string) (bool, error) {
	var count int64
	err := s.db.Model(&models.User{}).Where("email = ?", email).Count(&count).Error
	return count > 0, err
}

// GetUserLoginHistory 获取用户登录历史
func (s *UserService) GetUserLoginHistory(userID uint, page, pageSize int) ([]map[string]interface{}, int64, error) {
	var history []map[string]interface{}
	var total int64

	// 这里假设有一个登录日志表，实际项目中需要创建相应的模型
	// 暂时返回空数据
	return history, total, nil
}

// UpdateLastLogin 更新最后登录时间
func (s *UserService) UpdateLastLogin(userID uint) error {
	now := time.Now()
	return s.db.Model(&models.User{}).Where("id = ?", userID).Update("last_login_at", &now).Error
}

// AssignUserRoles 分配用户角色
func (s *UserService) AssignUserRoles(userID string, roleIDs []string) error {
	// 这个方法应该在权限服务中实现，这里只是占位
	return nil
}

// AssignRole 分配角色
func (s *UserService) AssignRole(userID, roleID string) error {
	// 这个方法应该在权限服务中实现，这里只是占位
	return nil
}

// RemoveRole 移除角色
func (s *UserService) RemoveRole(userID, roleID string) error {
	// 这个方法应该在权限服务中实现，这里只是占位
	return nil
}